import 'dart:io';

import 'package:get/get.dart';

import '../models/index.dart';
import '../services/index.dart';
import '../utils/index.dart';
import '../values/index.dart';

/// 网盘服务
class FileAssembleService extends GetxService {
  static FileAssembleService get to => Get.find();

  String baseUrl() {
    return O2ApiManager.instance
            .getModuleBaseUrl(O2DistributeModuleEnum.x_file_assemble_control) ??
        '';
  }
  /// 企业网盘 需要安装的服务
  String v3BaseUrl() {
    return O2ApiManager.instance
            .getModuleBaseUrl(O2DistributeModuleEnum.x_pan_assemble_control) ??
        '';
  }
  /// 是否有企业网盘
  bool isV3() {
    return SharedPreferenceService.to.getBool(SharedPreferenceService.v3PanAppIsInstallKey);
  }
 
  /// 工作区
  Future<List<CloudDiskZoneInfo>?> v3ZoneList() async {
    try {
      ApiResponse response =
          await O2HttpClient.instance.get('${v3BaseUrl()}jaxrs/zone/list');
      final list = response.data == null ? [] : response.data as List;
      return list.map((e) => CloudDiskZoneInfo.fromJson(e)).toList();
    } catch (err, stackTrace) {
      OLogger.e('工作区列表查询失败', err, stackTrace);
    }
    return null;
  }

   /// 收藏
  Future<List<CloudDiskZoneInfo>?> v3FavoriteList() async {
    try {
      ApiResponse response =
          await O2HttpClient.instance.get('${v3BaseUrl()}jaxrs/favorite/list');
      final list = response.data == null ? [] : response.data as List;
      return list.map((e) => CloudDiskZoneInfo.fromJson(e)).toList();
    } catch (err, stackTrace) {
      OLogger.e('收藏列表查询失败', err, stackTrace);
    }
    return null;
  }

  /// 是否运行创建工作区
  Future<ValueBoolData?> v3ZoneCanCreate() async {
    try {
      ApiResponse response =
          await O2HttpClient.instance.get('${v3BaseUrl()}jaxrs/config/is/zone/creator');
      return ValueBoolData.fromJson(response.data);
    } catch (err, stackTrace) {
      OLogger.e('工作区列表查询失败', err, stackTrace);
    }
    return null;
  }
  /// 创建工作区
  Future<IdData?> v3CreateZone(CloudDiskZonePost post) async {
    try {
      ApiResponse response =
          await O2HttpClient.instance.post('${v3BaseUrl()}jaxrs/zone', post.toJson());
      return IdData.fromJson(response.data);
    } catch (err, stackTrace) {
      OLogger.e('创建工作区失败', err, stackTrace);
    }
    return null;
  }

  /// 更新工作区
  Future<ValueBoolData?> v3UpdateZone(String id, CloudDiskZonePost post) async {
    try {
      ApiResponse response =
          await O2HttpClient.instance.post('${v3BaseUrl()}jaxrs/zone/$id/update', post.toJson());
      return ValueBoolData.fromJson(response.data);
    } catch (err, stackTrace) {
      OLogger.e('更新工作区失败', err, stackTrace);
    }
    return null;
  }
  /// 删除工作区
  Future<ValueBoolData?> v3DeleteZone(String id) async {
    try {
      ApiResponse response =
          await O2HttpClient.instance.delete('${v3BaseUrl()}jaxrs/zone/$id');
      return ValueBoolData.fromJson(response.data);
    } catch (err, stackTrace) {
      OLogger.e('删除工作区失败', err, stackTrace);
    }
    return null;
  }

  /// 加入收藏
  Future<IdData?> v3CreateFavorite(CloudDiskFavoritePost post) async {
    try {
      ApiResponse response =
          await O2HttpClient.instance.post('${v3BaseUrl()}jaxrs/favorite', post.toJson());
      return IdData.fromJson(response.data);
    } catch (err, stackTrace) {
      OLogger.e('加入收藏失败', err, stackTrace);
    }
    return null;
  }

  /// 更新收藏
  Future<ValueBoolData?> v3UpdateFavorite(String id, CloudDiskFavoritePost post) async {
    try {
      ApiResponse response =
          await O2HttpClient.instance.post('${v3BaseUrl()}jaxrs/favorite/$id/update', post.toJson());
      return ValueBoolData.fromJson(response.data);
    } catch (err, stackTrace) {
      OLogger.e('更新收藏失败', err, stackTrace);
    }
    return null;
  }
  /// 删除收藏
  Future<ValueBoolData?> v3DeleteFavorite(String id) async {
    try {
      ApiResponse response =
          await O2HttpClient.instance.delete('${v3BaseUrl()}jaxrs/favorite/$id');
      return ValueBoolData.fromJson(response.data);
    } catch (err, stackTrace) {
      OLogger.e('删除收藏失败', err, stackTrace);
    }
    return null;
  }

  /// 获取文件列表
  Future<List<FileInfo>?> listFileByFolderIdV3(String folderId, {String orderBy = 'updateTime'}) async {
    try {
      final url = '${v3BaseUrl()}jaxrs/attachment3/list/folder/$folderId/order/by/$orderBy/desc/true';
      ApiResponse response = await O2HttpClient.instance.get(url);
      var list = response.data == null ? [] : response.data as List;
      return list.map((e) => FileInfo.fromJson(e)).toList();
    } catch (err, stackTrace) {
      OLogger.e('获取文件列表失败', err, stackTrace);
    }
    return null;
  }


  /// 获取文件夹列表
  Future<List<FolderInfo>?> listFolderByParentV3(String folderId, {String orderBy = 'updateTime'}) async {
    try {
      final url =  '${v3BaseUrl()}jaxrs/folder3/list/$folderId/order/by/$orderBy/desc/true';
      ApiResponse response = await O2HttpClient.instance.get(url);
      var list = response.data == null ? [] : response.data as List;
      return list.map((e) => FolderInfo.fromJson(e)).toList();
    } catch (err, stackTrace) {
      OLogger.e('获取文件夹列表失败', err, stackTrace);
    }
    return null;
  }


  /// 创建文件夹
  Future<IdData?> createFolderV3(FolderPost post) async {
    try {
      ApiResponse response = await O2HttpClient.instance
          .post('${v3BaseUrl()}jaxrs/folder3', post.toJson());
      return IdData.fromJson(response.data);
    } catch (err, stackTrace) {
      OLogger.e('更新文件夹失败', err, stackTrace);
    }
    return null;
  }

  /// 更新文件夹
  Future<IdData?> renameFolderV3(String id, String newName) async {
    try {
      Map<String, dynamic> map = {
        "name": newName
      };
      ApiResponse response = await O2HttpClient.instance
          .post('${v3BaseUrl()}jaxrs/folder3/$id/update/name',  map);
      return IdData.fromJson(response.data);
    } catch (err, stackTrace) {
      OLogger.e('更新文件夹失败', err, stackTrace);
    }
    return null;
  }

  /// 删除文件夹
  Future<IdData?> deleteFolderV3(String id) async {
    try {
      ApiResponse response =
          await O2HttpClient.instance.delete('${v3BaseUrl()}jaxrs/folder3/$id');
      return IdData.fromJson(response.data);
    } catch (err, stackTrace) {
      OLogger.e('删除文件夹失败', err, stackTrace);
    }
    return null;
  }


  /// 更新文件
  Future<IdData?> renameFileV3(String id, String newName) async {
    try {
       Map<String, dynamic> map = {
        "name": newName
      };
      ApiResponse response = await O2HttpClient.instance
          .post('${v3BaseUrl()}jaxrs/attachment3/$id/update/name', map);
      return IdData.fromJson(response.data);
    } catch (err, stackTrace) {
      OLogger.e('更新文件失败', err, stackTrace);
    }
    return null;
  }

  /// 删除文件
  Future<IdData?> deleteFileV3(String id) async {
    try {
      ApiResponse response = await O2HttpClient.instance
          .delete('${v3BaseUrl()}jaxrs/attachment3/$id');
      return IdData.fromJson(response.data);
    } catch (err, stackTrace) {
      OLogger.e('删除文件失败', err, stackTrace);
    }
    return null;
  }
 
  /// 云盘 上传文件
  ///
  /// [folderId]  顶级目录用：O2.o2DefaultPageFirstKey
  Future<IdData?> uploadFileV3(String folderId, File file, {void Function(int, int)? onSendProgress}) async {
    try {
      ApiResponse response = await O2HttpClient.instance.postUploadFile(
          '${v3BaseUrl()}jaxrs/attachment3/upload/folder/$folderId', file, onSendProgress: onSendProgress);
      return IdData.fromJson(response.data);
    } catch (err, stackTrace) {
      OLogger.e('上传文件失败 ', err, stackTrace);
    }
    return null;
  }

  /// 将企业网盘工作区的文件和文件夹 移动到个人网盘目录
  Future<IdData?> saveToPersonV3(String folderId, ZoneFileSaveToPerson post) async {
    try {
      ApiResponse response = await O2HttpClient.instance.post(
          '${v3BaseUrl()}jaxrs/folder3/save/to/person/$folderId', post.toJson());
      return IdData.fromJson(response.data);
    } catch (err, stackTrace) {
      OLogger.e('移动到个人网盘目录失败 ', err, stackTrace);
    }
    return null;
  }

  /// 移动文件
  Future<IdData?> moveFileV3(String id, String folderId, String folderName) async {
    try {
      Map<String, dynamic> map = {
        "folder": folderId,
        "name": folderName
      };
      ApiResponse response = await O2HttpClient.instance
          .post('${v3BaseUrl()}jaxrs/attachment3/$id/move',  map);
      return IdData.fromJson(response.data);
    } catch (err, stackTrace) {
      OLogger.e('移动文件失败', err, stackTrace);
    }
    return null;
  }


  /// 移动文件夹
  Future<IdData?> moveFolderV3(String id, String folderId) async {
    try {
      Map<String, dynamic> map = {
        "superior": folderId
      };
      ApiResponse response = await O2HttpClient.instance
          .post('${v3BaseUrl()}jaxrs/folder3/$id/move',  map);
      return IdData.fromJson(response.data);
    } catch (err, stackTrace) {
      OLogger.e('移动文件夹失败', err, stackTrace);
    }
    return null;
  }










  /// 云盘图片列表 在线图片的地址
  String imageFileUrl(String fileId, int width, int height) {
    return '${baseUrl()}jaxrs/attachment2/$fileId/download/image/width/$width/height/$height';
  }

  /// 文件下载地址
  String fileDownloadUrl(String fileId, {needStream = true}) {
    if (needStream) {
      return '${baseUrl()}jaxrs/attachment2/$fileId/download/stream';
    }
    return '${baseUrl()}jaxrs/attachment2/$fileId/download';
  }
  String fileDownloadUrlV3(String fileId, {needStream = true}) {
    if (needStream) {
      return '${v3BaseUrl()}jaxrs/attachment3/$fileId/download/stream';
    }
    return '${v3BaseUrl()}jaxrs/attachment3/$fileId/download';
  }

  /// 顶层文件列表
  Future<List<FileInfo>?> listFileTop() async {
    try {
      var url = '${baseUrl()}jaxrs/attachment2/list/top';
      if(isV3()) {
        url = '${v3BaseUrl()}jaxrs/attachment2/list/top/order/by/updateTime/desc/true';
      }
      ApiResponse response = await O2HttpClient.instance
          .get(url);
      var list = response.data == null ? [] : response.data as List;
      return list.map((e) => FileInfo.fromJson(e)).toList();
    } catch (err, stackTrace) {
      OLogger.e('获取顶层文件列表失败', err, stackTrace);
    }
    return null;
  }

  /// 获取文件列表
  Future<List<FileInfo>?> listFileByParent(String parentId) async {
    try {
      var url = '${baseUrl()}jaxrs/attachment2/list/folder/$parentId';
      if(isV3()) {
        url = '${v3BaseUrl()}jaxrs/attachment2/list/folder/$parentId/order/by/updateTime/desc/true';
      }
      ApiResponse response = await O2HttpClient.instance.get(url);
      var list = response.data == null ? [] : response.data as List;
      return list.map((e) => FileInfo.fromJson(e)).toList();
    } catch (err, stackTrace) {
      OLogger.e('获取文件列表失败', err, stackTrace);
    }
    return null;
  }

  /// 顶层文件夹列表
  Future<List<FolderInfo>?> listFolderTop() async {
    try {
      var url = '${baseUrl()}jaxrs/folder2/list/top';
      if(isV3()) {
        url = '${v3BaseUrl()}jaxrs/folder2/list/top/order/by/updateTime/desc/true';
      }
      ApiResponse response =
          await O2HttpClient.instance.get(url);
      var list = response.data == null ? [] : response.data as List;
      return list.map((e) => FolderInfo.fromJson(e)).toList();
    } catch (err, stackTrace) {
      OLogger.e('获取顶层文件夹列表失败', err, stackTrace);
    }
    return null;
  }

  /// 获取文件夹列表
  Future<List<FolderInfo>?> listFolderByParent(String parentId) async {
    try {
      var url = '${baseUrl()}jaxrs/folder2/list/$parentId';
      if(isV3()) {
        url = '${v3BaseUrl()}jaxrs/folder2/list/$parentId/order/by/updateTime/desc/true';
      }
      ApiResponse response = await O2HttpClient.instance.get(url);
      var list = response.data == null ? [] : response.data as List;
      return list.map((e) => FolderInfo.fromJson(e)).toList();
    } catch (err, stackTrace) {
      OLogger.e('获取文件夹列表失败', err, stackTrace);
    }
    return null;
  }

  /// 创建文件夹
  Future<IdData?> createFolder(FolderPost post) async {
    try {
      ApiResponse response = await O2HttpClient.instance
          .post('${baseUrl()}jaxrs/folder2', post.toJson());
      return IdData.fromJson(response.data);
    } catch (err, stackTrace) {
      OLogger.e('更新文件夹失败', err, stackTrace);
    }
    return null;
  }

  /// 更新文件夹
  Future<IdData?> updateFolder(FolderInfo folder) async {
    try {
      ApiResponse response = await O2HttpClient.instance
          .put('${baseUrl()}jaxrs/folder2/${folder.id}', folder.toJson());
      return IdData.fromJson(response.data);
    } catch (err, stackTrace) {
      OLogger.e('更新文件夹失败', err, stackTrace);
    }
    return null;
  }

  /// 删除文件夹
  Future<IdData?> deleteFolder(String id) async {
    try {
      ApiResponse response =
          await O2HttpClient.instance.delete('${baseUrl()}jaxrs/folder2/$id');
      return IdData.fromJson(response.data);
    } catch (err, stackTrace) {
      OLogger.e('删除文件夹失败', err, stackTrace);
    }
    return null;
  }

  /// 更新文件
  Future<IdData?> updateFile(FileInfo file) async {
    try {
      ApiResponse response = await O2HttpClient.instance
          .put('${baseUrl()}jaxrs/attachment2/${file.id}', file.toJson());
      return IdData.fromJson(response.data);
    } catch (err, stackTrace) {
      OLogger.e('更新文件失败', err, stackTrace);
    }
    return null;
  }

  /// 删除文件
  Future<IdData?> deleteFile(String id) async {
    try {
      ApiResponse response = await O2HttpClient.instance
          .delete('${baseUrl()}jaxrs/attachment2/$id');
      return IdData.fromJson(response.data);
    } catch (err, stackTrace) {
      OLogger.e('删除文件失败', err, stackTrace);
    }
    return null;
  }

  /// 分享
  Future<IdData?> share(CloudDiskShareForm post) async {
    try {
      post.shareType = 'member'; // 目前暂时没有密码分享
      ApiResponse response = await O2HttpClient.instance
          .post('${baseUrl()}jaxrs/share', post.toJson());
      return IdData.fromJson(response.data);
    } catch (err, stackTrace) {
      OLogger.e('分享失败', err, stackTrace);
    }
    return null;
  }

  /// 云盘 上传文件
  ///
  /// [folderId]  顶级目录用：O2.o2DefaultPageFirstKey
  Future<IdData?> uploadFile(String folderId, File file, {void Function(int, int)? onSendProgress}) async {
    try {
      ApiResponse response = await O2HttpClient.instance.postUploadFile(
          '${baseUrl()}jaxrs/attachment2/upload/folder/$folderId', file, onSendProgress: onSendProgress);
      return IdData.fromJson(response.data);
    } catch (err, stackTrace) {
      OLogger.e('上传文件失败 ', err, stackTrace);
    }
    return null;
  }

  /// 根据类型获取文件列表
  ///
  /// 分页查询文件
  Future<List<FileInfo>?> listFileByType(String fileType, int page,
      {int count = O2.o2DefaultPageSize}) async {
    try {
      final post = FileSearchPost(fileType: fileType);
      ApiResponse response = await O2HttpClient.instance.post(
          '${baseUrl()}jaxrs/attachment2/list/type/$page/size/$count',
          post.toJson());
      var list = response.data == null ? [] : response.data as List;
      return list.map((e) => FileInfo.fromJson(e)).toList();
    } catch (err, stackTrace) {
      OLogger.e('根据类型获取文件列表失败', err, stackTrace);
    }
    return null;
  }

  /// 分享给我的列表
  ///
  /// [fileType] 分享的文件类型:文件(attachment)|目录(folder)|全部({0})
  Future<List<ShareFileInfo>?> listShareToMe(
      {String fileType = O2.o2DefaultPageFirstKey}) async {
    try {
      if (fileType != 'attachment' && fileType != 'folder') {
        fileType = O2.o2DefaultPageFirstKey;
      }
      ApiResponse response = await O2HttpClient.instance
          .get('${baseUrl()}jaxrs/share/list/to/me2/$fileType');
      var list = response.data == null ? [] : response.data as List;
      return list.map((e) => ShareFileInfo.fromJson(e)).toList();
    } catch (err, stackTrace) {
      OLogger.e('分享给我的列表失败', err, stackTrace);
    }
    return null;
  }

  /// 我分享的列表
  ///
  /// [fileType] 分享的文件类型:文件(attachment)|目录(folder)|全部({0})
  Future<List<ShareFileInfo>?> listMyShare(
      {String fileType = O2.o2DefaultPageFirstKey}) async {
    try {
      if (fileType != 'attachment' && fileType != 'folder') {
        fileType = O2.o2DefaultPageFirstKey;
      }
      ApiResponse response = await O2HttpClient.instance
          .get('${baseUrl()}jaxrs/share/list/my2/member/$fileType');
      var list = response.data == null ? [] : response.data as List;
      return list.map((e) => ShareFileInfo.fromJson(e)).toList();
    } catch (err, stackTrace) {
      OLogger.e('我分享的列表失败', err, stackTrace);
    }
    return null;
  }

  /// 分享保存到网盘
  Future<ValueBoolData?> shareSaveToPan(
      String shareId, String fileId, String folderId,
      {String? password}) async {
    try {
      final Map<String, dynamic> map = {};
      if (password != null && password.isNotEmpty) {
        map["password"] = password;
      }
      ApiResponse response = await O2HttpClient.instance.post(
          '${baseUrl()}jaxrs/share/share/$shareId/file/$fileId/folder/$folderId',
          map);
      return ValueBoolData.fromJson(response.data);
    } catch (err, stackTrace) {
      OLogger.e('分享保存到网盘失败', err, stackTrace);
    }
    return null;
  }

  /// 屏蔽分享过来的文件
  Future<IdData?> shareFileShield(String id) async {
    try {
      ApiResponse response =
          await O2HttpClient.instance.get('${baseUrl()}jaxrs/share/shield/$id');
      return IdData.fromJson(response.data);
    } catch (err, stackTrace) {
      OLogger.e('屏蔽分享过来的文件失败', err, stackTrace);
    }
    return null;
  }

  ///  取消分享
  Future<ValueBoolData?> shareFileDelete(String id) async {
    try {
      ApiResponse response =
          await O2HttpClient.instance.delete('${baseUrl()}jaxrs/share/$id');
      return ValueBoolData.fromJson(response.data);
    } catch (err, stackTrace) {
      OLogger.e('删除分享的文件失败', err, stackTrace);
    }
    return null;
  }

  /// 上传图片
  ///
  /// 流程和 cms 使用
  Future<IdData?> uploadImageWithReferencetype(
      String referencetype, String reference, File file,
      {int scale = 0}) async {
    try {
      ApiResponse response = await O2HttpClient.instance.putUploadFile(
          '${baseUrl()}jaxrs/file/upload/referencetype/$referencetype/reference/$reference/scale/$scale',
          file);
      return IdData.fromJson(response.data);
    } catch (err, stackTrace) {
      OLogger.e(
          '上传图片失败 referencetype: $referencetype reference: $reference scale: $scale',
          err,
          stackTrace);
    }
    return null;
  }

  /// 上传图片
  ///
  /// 脑图使用的
  Future<String?> uploadImageForMindMap(String mindMapId, File file,
      {int scale = 800}) async {
    IdData? idData = await uploadImageWithReferencetype(
        'mindInfo', mindMapId, file,
        scale: scale);
    if (idData != null) {
      return idData.id!;
    }
    return null;
  }
}
